<template>
    <div>
        <h3>Vuex的演示组件</h3>
        <!-- 
            vuex中state的东西，如何在视图部分在视图部分直接展示？
        -->
        <div>vuex中store对象获取的年龄：{{ $store.state.age }}</div>
        <div>vuex中mapState方法的年龄：{{ age }}</div>
        <div>vuex中mapState方法的用户名：{{ username }}</div>
        <div>{{ dealAge }}</div>
        <button @click="changeData">按钮</button>
    </div>
</template>

<script>
// 语法2的使用需要先导入4个辅助方法
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
// 这四个辅助方法，需要进行分类，每个属性使用的代码为止可能不一样
// 例如：
//      写在计算（computed）属性中的方法：mapState、mapGetters
//      写在方法（methods）属性中的方法；mapMutations、mapActions
export default {
    mounted() {
        // 语法1，1. state的打印输出
        // 语法：this.$store.state.xxxx
        console.log("通过store对象获取" + this.$store.state.username);
        console.log("通过store对象获取" + this.$store.state.age);
        // 语法：this.$store.commit(mutations中对应的方法名,载荷)
        this.$store.commit("setUserName", "田七");
        // 以下为执行异步代码的示例，不能在mutations中写异步代码，如果写了虽然不会有语法错误，但是会影响我们在使用vue的调试工具的时候判断。其表现效果为，工具会立即记录修改，但是数据不会更新。而正常的理想效果是：先改数据，后记录修改。
        // this.$store.commit("setAge", 55);
        // 语法：this.$store.dispatch(actions中对应的方法名,载荷)
        this.$store.dispatch("setAgeAsync", 88);
        // 语法：this.$store.getters.xxxx
        console.log(this.$store.getters.dealAge);

        // 语法2，1. 通过映射的方式获取state的数据
        console.log("通过mapState方法获取" + this.username);
        console.log("通过mapState方法获取" + this.age);
        // 语法：通过映射的方法执行mutations里的方法
        //          语法： this.mutations中的方法名(载荷)
        this.setUserName("王八");
        // 语法：通过映射的方法执行actions里的方法
        //          语法： this.actions中的方法名(载荷)
        this.setAgeAsync(99);
        // 语法：通过映射的方法执行getters里的数据
        console.log(this.dealAge);
    },
    // 语法2： 2. 计算属性中放辅助方法
    computed: {
        // 该方法根据参数中列出的数据名称去store中获取对应的数据，将数据通过映射，映射成组件自身的属性。例如，通过mapState获取username、age
        // 如果后续要取的数据比较多，建议用mapState方法【批量获取并绑定】
        ...mapState(["username", "age"]),
        // 该方法根据参数中列出的数据名称去store中获取对应的数据。。。
        ...mapGetters(["dealAge"]),
    },
    methods: {
        changeData() {
            // 注意点1：被映射成组件自身的属性，属性为只读属性，不能赋值
            // this.username = "李四";
            // 注意点2：通过$store的方式直接给其赋值，虽然不报错，但是只能改自己组件层面的数据，无法影响store数据，因此没有意义
            // this.$store.state.username = "王五";
        },
        // 将目标的方法映射成当前组件自身的方法，后续如果有很多方法需要在当前组件中使用，建议使用mapMutations方法进行映射
        ...mapMutations(["setUserName"]),
        // 将目标的方法映射成当前组件自身的方法，后续如果有很多地方要在当前组件中使用，建议使用mapActions方法进行映射
        ...mapActions(["setAgeAsync"]),
    },
};
</script>

<style></style>
